#pragma once
/*
 * mysql record set wrapper.
 */

#include "mysql_db.h"
#include "mysql.h"
#include "type.h"
#include <assert.h>

namespace SMysqlSpace {
    #define MAX_FIELD_SIZE 512
	typedef struct {
		char szFiled[MAX_FIELD_SIZE];
	} SFiledName;

	// mysql record set.
	class CMysqlRecordset : public IMysqlRecordset {
	public:
		CMysqlRecordset();
		explicit CMysqlRecordset(MYSQL_RES* poRes);
		virtual ~CMysqlRecordset();
		CMysqlRecordset(const CMysqlRecordset&) = delete;
		CMysqlRecordset operator=(const CMysqlRecordset&) = delete;

	public:
		virtual uint32 STDCALL GetRowsNum() const {
			return (uint32)mysql_num_rows(m_pstRes);
		}
		virtual uint32 STDCALL GetFieldsNum() const {
			return mysql_num_fields(m_pstRes);
		}
		virtual bool STDCALL Next() {
			m_arRow = mysql_fetch_row(m_pstRes);
			if (m_arRow != nullptr) {
				m_arLengths = mysql_fetch_lengths(m_pstRes);
			}
			return (nullptr != m_arRow);
		}

		// get field data
		virtual const char* STDCALL GetFieldOfIndex(uint32 dwIndex)const;
		virtual const char* STDCALL GetFieldOfName(const char* szField)const;
		virtual int STDCALL GetFieldLength(uint32 dwIndex);

		// release
		virtual void STDCALL Release();

	public:
		void AttachRowRes(MYSQL_RES* poRes);

	protected:
		void buildFieldData(MYSQL_RES* poRes);

	private:
		MYSQL_RES     *m_pstRes{nullptr};   // result.
		MYSQL_ROW     m_arRow{ nullptr };   // row data
		unsigned long *m_arLengths{nullptr};// row size
		SFiledName    *m_arField{nullptr};  // index to name
		int           m_fieldCount{ 0 };    // real size of field
	};
}